﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using CMS.Service.Repository;
using CMSApplication.Areas.Administration.Models;
using CMS.Common.Mvc;
using CMS.Data;
using CMS.Common.Helpers;
using CMS.Service.EnumHelper;
using CMS.Service.Common;
using OfficeOpenXml;
using OfficeOpenXml.Style;
using OfficeOpenXml.Drawing.Chart;

namespace CMSApplication.Areas.Administration.Controllers
{
    public class WorkController : UTController
    {
        private WorkRepository wrk_srv = new WorkRepository();
        private UserRepositry user_srv = new UserRepositry();
        private CustomerRepository customer_srv = new CustomerRepository();
        private CustomerTypeRepository customer_type_srv = new CustomerTypeRepository();        
        
        public ActionResult Index()
        {
            WorkSearchModel model = new WorkSearchModel()
            {
                AssignOnFrom = DateTime.MinValue,
                AssignOnTo = DateTime.MinValue,
                Page = 1,
                Type = 1
            };
            model.GetDataForSL();
            return View(model);
        }

        [Authorize(Roles = "Administrator,Manager")]
        public ActionResult List(WorkSearchModel req)
        {
            if (req.AssignOnFrom > DateTime.MinValue)
            {
                req.AssignOnFrom = new DateTime(req.AssignOnFrom.Year, req.AssignOnFrom.Month, req.AssignOnFrom.Day);
            }
            if (req.AssignOnTo > DateTime.MinValue)
            {
                req.AssignOnTo = new DateTime(req.AssignOnTo.Year, req.AssignOnTo.Month, req.AssignOnTo.Day).AddDays(1);
            }
            List<WorkModel> res = new List<WorkModel>();

            var status_lst = EnumHelper.Get_Enum_Wrk_Status();
            var customer_lst = customer_srv.List();
            var staff_lst = user_srv.List();

            var c = wrk_srv.List(req.Keys, req.CustomerId, req.StaffId, req.AssignOnFrom, req.AssignOnTo, req.Status, req.OrderBy);
            foreach (var item in c)
            {
                WorkModel ml = new WorkModel();
                WorkModel.MapFrom(item, ref  ml);

                var status = status_lst.Where(x => x.Key == ml.Status).FirstOrDefault();
                var customer = customer_lst.Where(x => x.Id == ml.AssignCustomer).FirstOrDefault();
                var staff = staff_lst.Where(x => x.Id == ml.AssignStaff).FirstOrDefault();

                if (status_lst.Count(x => x.Key == ml.Status) > 0) ml.StatusName = status_lst.Where(x => x.Key == ml.Status).First().Value;
                if (customer != null)
                {
                    ml.CustomerName = string.Format("{0} - {1}", customer.Id.ToString().PadLeft(4, '0'), customer.Name);
                    ml.CustomerAddr = customer.Addr;
                    ml.CustomerPhone = customer.Phone;
                }
                if (staff != null) ml.StaffName = string.Format("{0} - {1}", staff.Id.ToString().PadLeft(4, '0'), staff.FullName);

                res.Add(ml);
            }

            var ListNewsPageSize = new PagedData<WorkModel>();
            if (res.Count() > 0)
            {
                ListNewsPageSize.Data = res.Skip(PageSize * (req.Page - 1)).Take(PageSize).ToList();
                if (ListNewsPageSize.Data.Count() == 0)
                {
                    ListNewsPageSize.Data = res.Skip(PageSize * (req.Page - 2)).Take(PageSize).ToList();
                }
                ListNewsPageSize.NumberOfPages = Convert.ToInt32(Math.Ceiling((double)res.Count() / PageSize));
                ListNewsPageSize.CurrentPage = req.Page <= ListNewsPageSize.NumberOfPages ? req.Page : ListNewsPageSize.NumberOfPages;
            }
            else
            {
                ListNewsPageSize.Data = new List<WorkModel>();
                ListNewsPageSize.NumberOfPages = 0;
                ListNewsPageSize.CurrentPage = 0;
            }

            switch (req.Type)
            {
                case 1:
                    return PartialView("_List", ListNewsPageSize);
                case 2:
                    return ExportExcel(res);
                default:
                    return PartialView("_List", ListNewsPageSize);
            }
        }

        [Authorize(Roles = "Administrator,Manager")]
        public ActionResult Add(int? CustomerId)
        {
            WorkModel model = new WorkModel();
            model.AssignCustomer = CustomerId.HasValue ? CustomerId.Value : 0;
            model.AssignOn = DateTime.Now;
            model.Status = (int)Enum_Wrk_Status.Complete;
            model.Collected = 0;
            model.GetDataForSL();
            return View(model);
        }

        [Authorize(Roles = "Administrator,Manager")]
        public ActionResult Edit(int id)
        {
            WorkModel model = new WorkModel();
            var entity = wrk_srv.GetById(id);
            WorkModel.MapFrom(entity, ref model);
            model.GetDataForSL();
            return View(model);
        }

        [HttpPost]
        [ValidateInput(false)]
        [Authorize(Roles = "Administrator,Manager")]
        public ActionResult AddOrUpdate(WorkModel model)
        {
            if (model.Id == 0)
            {
                model.CreatedOn = DateTime.Now;
            }
            else
            {
                model.LastUpdatedOn = DateTime.Now;
            }
            Work entity = new Work();
            WorkModel.MapFrom(model, ref entity);
            wrk_srv.CreateOrUpdate(entity);

            return JsonSuccess(model.IsContinue ? Url.Action("Add") : Url.Action("Index"));
        }

        [Authorize(Roles = "Administrator,Manager")]
        public ActionResult Delete(int Id)
        {
            wrk_srv.Delete(Id);
            return Json(null, JsonRequestBehavior.AllowGet);
        }

        public ActionResult ExportExcel(List<WorkModel> model)
        {
            foreach (var item in model)
            {
                if (item.AssignOn.HasValue)
                {
                    item.AssignOn = new DateTime(item.AssignOn.Value.Year, item.AssignOn.Value.Month, item.AssignOn.Value.Day);
                }
            }
            var data = model.GroupBy(x => new { x.AssignOn });

            using (var package = new ExcelPackage())
            {
                package.Workbook.Worksheets.Add(string.Format("{0:yyyy-MM-dd}", DateTime.Now));
                ExcelWorksheet ws = package.Workbook.Worksheets[1];
                ws.Name = "DS Công Việc";
                ws.Cells.Style.Font.Size = 12;
                ws.Cells.Style.Font.Name = "Times New Roman";

                int row = 1;
                ws.Cells[row, 1].Value = "BÁO CÁO CÔNG VIỆC";
                ws.Cells[row, 1].Style.Font.Size = 22;
                ws.Cells[row, 1].Style.Font.Bold = true;
                ws.Cells[row, 1, row, 11].Merge = true;
                ws.Cells[row, 1, row, 11].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;

                List<string> ws_header = new List<string>() { "STT", "TÊN KHÁCH HÀNG", "ĐỊA CHỈ", "SỐ ĐIỆN THOẠI", "NỘI DUNG", "NHÂN VIÊN", "SỐ TIỀN", "TÌNH TRẠNG", "VẬT TƯ", "SỐ HÓA ĐƠN", "GHI CHÚ" };
                int COL_NO = 1, COL_CUSTOMER_NAME = 2, COL_CUSTOMER_ADDR = 3, COL_CUSTOMER_PHONE = 4, COL_CONTENT = 5, COL_STAFF_NAME = 6, COL_COLLECTED = 7, COL_STATUS_NAME = 8, COL_COST = 9, COL_BILLNUM = 10, COL_NOTE = 11;

                row += 2;
                for (int i = 1; i <= ws_header.Count; i++)
                {
                    ws.Cells[row, i].Value = ws_header[i - 1];
                    ws.Cells[row, i].Style.Font.Size = 11;
                    ws.Cells[row, i].Style.Font.Bold = true;
                    ws.Cells[row, i].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                }

                foreach (var item1 in data)
                {
                    row += 2;
                    ws.Cells[row, 1].Value = "NGÀY " + (item1.Key.AssignOn.HasValue ? string.Format("{0:dd/MM/yyyy}", item1.Key.AssignOn.Value) : "N/A");
                    ws.Cells[row, 1].Style.Font.Size = 16;
                    ws.Cells[row, 1].Style.Font.Bold = true;
                    ws.Cells[row, 1, row, 11].Merge = true;
                    ws.Cells[row, 1, row, 11].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;

                    int no = 0;
                    foreach (var item2 in item1)
                    {
                        row++;
                        ws.Cells[row, COL_NO].Value = ++no;
                        ws.Cells[row, COL_CUSTOMER_NAME].Value = item2.CustomerName;
                        ws.Cells[row, COL_CUSTOMER_ADDR].Value = item2.CustomerAddr;
                        ws.Cells[row, COL_CUSTOMER_PHONE].Value = item2.CustomerPhone;
                        ws.Cells[row, COL_CONTENT].Value = item2.Content;
                        ws.Cells[row, COL_STAFF_NAME].Value = item2.StaffName;
                        ws.Cells[row, COL_COLLECTED].Value = item2.Collected;
                        ws.Cells[row, COL_STATUS_NAME].Value = item2.StatusName;
                        ws.Cells[row, COL_COST].Value = item2.Cost;
                        ws.Cells[row, COL_BILLNUM].Value = item2.BillNum;
                        ws.Cells[row, COL_NOTE].Value = item2.Note;
                        ws.Cells[row, COL_NO].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                    }
                }

                /* TODO: Comments
                ws.Cells[row_index, 2].Style.Font.Italic = true;*/

                ws.View.FreezePanes(4, 2);

                for (int i = 1; i <= ws_header.Count; i++)
                {
                    if (i == COL_CONTENT || i == COL_NOTE)
                    {
                        ws.Column(i).Width = 15;
                    }
                    else
                    {
                        ws.Column(i).AutoFit();
                    }
                }
                
                /* TODO: Comments
                var chart = ws.Drawings.AddChart("chart1", eChartType.AreaStacked);

                chart.SetPosition(0, 630);
                chart.SetSize(800, 600);

                var series = chart.Series.Add(ws.Cells["A2:A46"], ws.Cells["B2:B46"]);*/

                var memoryStream = package.GetAsByteArray();
                var fileName = string.Format("Report_{0:ddMMyy}.xlsx", DateTime.Now);
                // mimetype from http://stackoverflow.com/questions/4212861/what-is-a-correct-mime-type-for-docx-pptx-etc
                return base.File(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
            }
        }

        public ActionResult Customer_Info(int Id)
        {
            var entity = customer_srv.GetById(Id);
            if (entity != null)
            {
                return Json(new {
                    Id = entity.Id,
                    Name = string.Format("{0}", entity.Name),
                    Addr = string.Format("{0}", entity.Addr),
                    Phone = string.Format("{0}", entity.Phone)
                }, JsonRequestBehavior.AllowGet);
            }
            return Json(null, JsonRequestBehavior.AllowGet);
        }

        [Authorize(Roles = "Administrator,Manager")]
        public ActionResult Customer_Popup_Index()
        {
            CustomerSearchModel model_res = new CustomerSearchModel();
            model_res.GetDataForSL();
            return PartialView("_Customer_Popup_Index", model_res);
        }

        [Authorize(Roles = "Administrator,Manager")]
        public ActionResult Customer_Popup_List(CustomerSearchModel model_req)
        {
            if (model_req.CreatedOnFrom > DateTime.MinValue)
            {
                model_req.CreatedOnFrom = new DateTime(model_req.CreatedOnFrom.Year, model_req.CreatedOnFrom.Month, model_req.CreatedOnFrom.Day);
            }
            if (model_req.CreatedOnTo > DateTime.MinValue)
            {
                model_req.CreatedOnTo = new DateTime(model_req.CreatedOnTo.Year, model_req.CreatedOnTo.Month, model_req.CreatedOnTo.Day).AddDays(1);
            }

            var c = customer_srv.Search(model_req.Keys, model_req.Type, 0, model_req.CreatedOnFrom, model_req.CreatedOnTo);
            var ct = customer_type_srv.List();
            List<CustomerModel> model_res = new List<CustomerModel>();
            foreach (var item in c)
            {
                CustomerModel cm = new CustomerModel();
                CustomerModel.Mapfrom(item, ref cm);
                var t = ct.Where(x => x.Id == item.Type).FirstOrDefault();
                cm.TypeName = t != null ? t.Name : "";
                model_res.Add(cm);
            }

            return PartialView("_Customer_Popup_List", model_res);
        }

        [HttpGet]
        [Authorize(Roles = "Administrator,Manager")]
        public ActionResult Customer_Popup_Add()
        {
            CustomerModel model_res = new CustomerModel();
            model_res.Id = 0;
            model_res.Type = 0;
            model_res.Active = true;
            model_res.GetDataForSL();
            return PartialView("_Customer_Popup_Add", model_res);
        }

        [HttpPost]
        [ValidateInput(false)]
        [Authorize(Roles = "Administrator,Manager")]
        public ActionResult Customer_Popup_Add(CustomerModel model_req, IEnumerable<HttpPostedFileBase> FileUp)
        {
            if (model_req.Name == null) model_req.Name = "";
            model_req.CreatedOn = DateTime.Now;
            Customer entity = new Customer();
            CustomerModel.Mapfrom(model_req, ref entity);
            return Json(new { Id = customer_srv.CreateOrUpdate(entity) });
        }
    }
}
